// CommandListBox.cpp : implementation file
//

#include "stdafx.h"
#include "CommandListBox.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCommandListBox

BEGIN_MESSAGE_MAP(CCommandListBox, CListBox)
	//{{AFX_MSG_MAP(CCommandListBox)
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCommandListBox message handlers

int CCommandListBox::ExtractCommandsFromResource(const BYTE * lpbBuffer, DWORD dwResourceSize)
{
	int nCommand = 0;
	
	DWORD dwPos = 2;	// skip the first two bytes
	while (dwResourceSize > dwPos)
	{
		LPVSCOMMAND pCommand = (LPVSCOMMAND)new VSCOMMAND;
		//	::ZeroMemory(pCommand, sizeof(VSCOMMAND));
		
		pCommand->wID = * ((WORD *)(&lpbBuffer[dwPos]));
		pCommand->wGroupID = * ((WORD *)(&lpbBuffer[dwPos + 2]));
		pCommand->bUnidentified[0] = lpbBuffer[dwPos + 4];
		pCommand->bUnidentified[1] = lpbBuffer[dwPos + 5];
		pCommand->wImageIndex = * ((WORD *)(&lpbBuffer[dwPos + 6]));
		pCommand->cbExtra = * ((WORD *)(&lpbBuffer[dwPos + 8]));

		pCommand->pbExtra = (LPBYTE)new BYTE[pCommand->cbExtra];
		::CopyMemory(pCommand->pbExtra, &lpbBuffer[dwPos + 10], pCommand->cbExtra);

		pCommand->pszID = (LPTSTR)pCommand->pbExtra;
		pCommand->pszMenu = pCommand->pszID + (_tcslen(pCommand->pszID) + 1);
		pCommand->pszLongDescription = pCommand->pszMenu + (_tcslen(pCommand->pszMenu) + 1);
		pCommand->pszShortDescription = pCommand->pszLongDescription + (_tcslen(pCommand->pszLongDescription) + 1);

		dwPos +=(10 + pCommand->cbExtra);
		
		int nIndex = AddCommand(pCommand);
		if(nIndex != LB_ERR)
		{
			nCommand++;
			continue;
		}

		delete[] pCommand->pbExtra;
		delete pCommand;
	}
	
	return nCommand;
}

int CCommandListBox::AddCommand(const LPVSCOMMAND pCommand)
{
	int nIndex = LB_ERR;
	
	if(_tcslen(pCommand->pszID) > 0)
	{
		LPVSCOMMAND pFound;
		if(m_commandMap.Lookup(pCommand->wID, pFound) == 0)
		{
			nIndex = AddString(pCommand->pszID);
			if(nIndex != LB_ERR)
			{
				if(SetItemDataPtr(nIndex, pCommand) == LB_ERR)
				{
					DeleteString(nIndex);
					
					return LB_ERR;
				}
			}
			m_commandMap.SetAt(pCommand->wID, pCommand);
		}
	}

	return nIndex;
}

const LPVSCOMMAND CCommandListBox::GetCommand(int nIndex)
{
	if(nIndex >= 0 && nIndex < GetCount())
	{
		return (const LPVSCOMMAND)GetItemDataPtr(nIndex);
	}

	return NULL;
}

int CCommandListBox::FindCommand(const WORD wID)
{
	for(int i = GetCount() - 1; i > 0; i--)
	{
		LPVSCOMMAND pCommand = (LPVSCOMMAND)GetItemDataPtr(i);
		if(pCommand->wID == wID)
			return i;
	}

	return LB_ERR;
}

int CCommandListBox::FindCommand(LPCTSTR pszID)
{
	for(int i = GetCount() - 1; i > 0; i--)
	{
		LPVSCOMMAND pCommand = (LPVSCOMMAND)GetItemDataPtr(i);
		if(_tcslen(pCommand->pszID) == _tcslen(pszID) && !_tcscmp(pCommand->pszID, pszID))
			return i;
	}

	return LB_ERR;
}

void CCommandListBox::RemoveAll()
{
//	int nCommand = GetCount();
//	for (int i = 0; i < nCommand; i++)
//	{
//		LPVSCOMMAND pCommand = (LPVSCOMMAND)GetItemDataPtr(i);
//		ASSERT(pCommand !=(LPVSCOMMAND) - 1);
//		if(pCommand) delete[] pCommand->pbExtra;
//		delete pCommand;
//	}

	POSITION pos = m_commandMap.GetStartPosition();

	WORD wID = 0;
	LPVSCOMMAND pCommand = NULL;
	while(pos)
	{
		m_commandMap.GetNextAssoc(pos, wID, pCommand);
		if(pCommand)
		{
			delete [] ((LPVSCOMMAND)pCommand)->pbExtra;
		}
		delete pCommand;
		pCommand = NULL;
	}

	m_commandMap.RemoveAll();
}

void CCommandListBox::OnDestroy() 
{
	CListBox::OnDestroy();
	
	// TODO: Add your message handler code here
	RemoveAll();
}

int CCommandListBox::Reload(CCommandListBox::CATEGORIES cat)
{
	ResetContent();

	POSITION pos = m_commandMap.GetStartPosition();

	int nCommand = 0;
	WORD wID = 0;
	LPVSCOMMAND pCommand = NULL;
	while(pos)
	{
		m_commandMap.GetNextAssoc(pos, wID, pCommand);

		if(pCommand)
		{
			if(IsCommandInCategory((LPVSCOMMAND)pCommand, cat))
			{
				int nIndex = AddString(((LPVSCOMMAND)pCommand)->pszID);
				if(nIndex != LB_ERR)
				{
					if(SetItemDataPtr(nIndex, pCommand) == LB_ERR) DeleteString(nIndex);
					else nCommand++;

					continue;
				}
			}
		}
	}

	return nCommand;
}

BOOL CCommandListBox::IsCommandInCategory(LPVSCOMMAND pCommand, CCommandListBox::CATEGORIES cat)
{
	switch(cat)
	{
	case CAT_FILE:
		if(32768 <= pCommand->wGroupID && 32793 >= pCommand->wGroupID || 32878 == pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_EDIT:
		if(32800 <= pCommand->wGroupID && 32836 >= pCommand->wGroupID || 33258 <= pCommand->wGroupID && 33286 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_VIEW:
		if(32868 == pCommand->wGroupID || 32874 == pCommand->wGroupID || 33185 <= pCommand->wGroupID && 33210 >= pCommand->wGroupID || 33344 == pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_WIZARDBAR:
		if(33252 <= pCommand->wGroupID && 33256 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_INSERT:
		if(32872 == pCommand->wGroupID || 33347 <= pCommand->wGroupID && 33352 >= pCommand->wGroupID || 33360 == pCommand->wGroupID || 33368 == pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_PROJECT:
		if(33472 <= pCommand->wGroupID && 33482 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_BUILD:
		if(33160 <= pCommand->wGroupID && 33166 >= pCommand->wGroupID || 33354 == pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_DEBUG:
		if(32896 <= pCommand->wGroupID && 32912 >= pCommand->wGroupID || 33361 <= pCommand->wGroupID && 33367 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_IMAGE:
		if(33024 <= pCommand->wGroupID && 33032 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_LAYOUT:
		if(33057 <= pCommand->wGroupID && 33082 >= pCommand->wGroupID || 32876 == pCommand->wGroupID || 33586 == pCommand->wGroupID || 33590 == pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_QUERY:
		if(52432 == pCommand->wGroupID || 52442 <= pCommand->wGroupID && 52454 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_DIAGRAM:
		if(52412 <= pCommand->wGroupID && 52420 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_TOOLS:
		if(32928 < pCommand->wGroupID && 32942 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_WINDOW:
		if(32960 <= pCommand->wGroupID && 32968 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_HELP:
		if(32992 <= pCommand->wGroupID && 33018 >= pCommand->wGroupID)
			return TRUE;
		break;

	case CAT_MACROS:
		return FALSE;
		break;

	case CAT_ADDINS:
		return FALSE;
		break;

	case CAT_ALL:
		return TRUE;
		break;

	default:
		break;
	}

	return FALSE;
}
